package net.orange.console.model.dataset;

import java.text.SimpleDateFormat;
import java.util.Date;

import javax.sql.RowSet;

import net.orange.architecture.system.SystemParameters;

/**
 * The smallest unit data, include the the data type & data.
 * 
 */
public class ConsoleData {
	/**
	 * The data type
	 */
	private ConsoleMetaData metaData;
	/**
	 * The number value.
	 */
	private long integerValue;

	/**
	 * The number value.
	 */
	private double numericValue;
	/**
	 * The String value.
	 */
	private String stringValue;
	/**
	 * The date value.
	 */
	private Date dateValue;
	/**
	 * The other value.
	 */
	private Object otherValue;

	/**
	 * Constructor with the Jdbc rowset and Meta Data, it will convert the
	 * current row set data to console data.
	 * 
	 * @param rowSet
	 *            The Jdbc row set
	 * @param metaData
	 *            The console meta data .
	 */
	public ConsoleData(RowSet rowSet, ConsoleMetaData metaData)
			throws Exception {

		String fieldName = metaData.getColumnName();
		this.metaData = metaData;

		if (metaData.getDataType() == ConsoleDataType.String)
			stringValue = rowSet.getString(fieldName);

		if (metaData.getDataType() == ConsoleDataType.Numberic)
			numericValue = rowSet.getDouble(fieldName);

		if (metaData.getDataType() == ConsoleDataType.Integer)
			integerValue = rowSet.getLong(fieldName);

		if (metaData.getDataType() == ConsoleDataType.Date)
			dateValue = rowSet.getDate(fieldName);

		if (metaData.getDataType() == ConsoleDataType.DateTime)
			dateValue = rowSet.getTimestamp(fieldName);

		if (metaData.getDataType() == ConsoleDataType.Other)
			throw new Exception("Unsupport Data Type");
	}

	/**
	 * Constructor with the console meta data and value.
	 * 
	 * @param metaData
	 *            The console meta data.
	 * @param stringValue
	 *            The string value;
	 * @throws Exception
	 */
	public ConsoleData(ConsoleMetaData metaData, String stringValue)
			throws Exception {
		this.metaData = metaData;

		if (metaData.getDataType() == ConsoleDataType.String)
			this.stringValue = stringValue;

		if (metaData.getDataType() == ConsoleDataType.Numberic)
			this.numericValue = Double.valueOf(stringValue);

		if (metaData.getDataType() == ConsoleDataType.Integer)
			this.integerValue = Integer.valueOf(stringValue);

		if (metaData.getDataType() == ConsoleDataType.Date) {
			SimpleDateFormat format = new SimpleDateFormat(
					SystemParameters.SRV_DATE_FORMAT);

			this.dateValue = (stringValue != null) ? format.parse(stringValue)
					: null;
		}

		if (metaData.getDataType() == ConsoleDataType.DateTime) {
			SimpleDateFormat format = new SimpleDateFormat(
					SystemParameters.SRV_DATETIME_FORMAT);

			this.dateValue = (stringValue != null) ? format.parse(stringValue)
					: null;
		}

		if (metaData.getDataType() == ConsoleDataType.Other)
			throw new Exception("Unsupport Data Type");
	}

	/**
	 * @return the metaData
	 */
	public ConsoleMetaData getMetaData() {
		return metaData;
	}

	/**
	 * @param metaData
	 *            the metaData to set
	 */
	public void setMetaData(ConsoleMetaData metaData) {
		this.metaData = metaData;
	}

	/**
	 * @return the numberValue
	 */
	public double getNumericValue() {
		if (metaData.getDataType() == ConsoleDataType.Numberic)
			return numericValue;
		if (metaData.getDataType() == ConsoleDataType.Integer)
			return integerValue;

		return numericValue;
	}

	/**
	 * @param numberValue
	 *            the numberValue to set
	 */
	public void setNumericValue(double numberValue) {
		this.numericValue = numberValue;
	}

	/**
	 * @return the stringValue
	 */
	public String getStringValue() {
		if (metaData != null) {
			if (metaData.getDataType() == ConsoleDataType.String)
				return (stringValue != null) ? stringValue : "";

			if (metaData.getDataType() == ConsoleDataType.Numberic)
				return String.valueOf(numericValue);

			if (metaData.getDataType() == ConsoleDataType.Integer)
				return String.valueOf(integerValue);

			if (metaData.getDataType() == ConsoleDataType.Date) {
				SimpleDateFormat format = new SimpleDateFormat(
						SystemParameters.SRV_DATE_FORMAT);
				return (dateValue != null) ? format.format(dateValue) : "";
			}

			if (metaData.getDataType() == ConsoleDataType.DateTime) {
				SimpleDateFormat format = new SimpleDateFormat(
						SystemParameters.SRV_DATETIME_FORMAT);
				return (dateValue != null) ? format.format(dateValue) : "";
			}
		}
		return (stringValue != null) ? stringValue : "";
	}

	/**
	 * @param stringValue
	 *            the stringValue to set
	 */
	public void setStringValue(String stringValue) {
		this.stringValue = stringValue;
	}

	/**
	 * @return the dateValue
	 */
	public Date getDateValue() {
		return dateValue;
	}

	/**
	 * @param dateValue
	 *            the dateValue to set
	 */
	public void setDateValue(Date dateValue) {
		this.dateValue = dateValue;
	}

	/**
	 * @return the dateValue
	 */
	public Date getDateTimeValue() {
		return dateValue;
	}

	/**
	 * @param dateValue
	 *            the dateValue to set
	 */
	public void setDateTimeValue(Date dateTimeValue) {
		this.dateValue = dateTimeValue;
	}

	/**
	 * @return the otherValue
	 */
	public Object getOtherValue() {
		return otherValue;
	}

	/**
	 * @param otherValue
	 *            the otherValue to set
	 */
	public void setOtherValue(Object otherValue) {
		this.otherValue = otherValue;
	}

	/**
	 * @return the integerValue
	 */
	public long getIntegerValue() {
		if (metaData.getDataType() == ConsoleDataType.Numberic)
			return (long) numericValue;
		if (metaData.getDataType() == ConsoleDataType.Integer)
			return integerValue;

		return integerValue;
	}

	/**
	 * @param integerValue
	 *            the integerValue to set
	 */
	public void setIntegerValue(long integerValue) {
		this.integerValue = integerValue;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	public boolean equals(Object otherValue) {
		if (!(otherValue instanceof ConsoleData))
			return false;

		if (!metaData.equals(((ConsoleData) otherValue).getMetaData()))
			return false;

		if (otherValue != null) {
			ConsoleData other = (ConsoleData) otherValue;

			if (metaData.getDataType() == ConsoleDataType.String
					&& getStringValue().equals(other.getStringValue()))
				return true;

			if (metaData.getDataType() == ConsoleDataType.Integer
					&& integerValue == other.getIntegerValue())
				return true;

			if (metaData.getDataType() == ConsoleDataType.Numberic
					&& numericValue == other.getNumericValue())
				return true;

			if (metaData.getDataType() == ConsoleDataType.Date
					&& dateValue.equals(other.getDateValue()))
				return true;

			if (metaData.getDataType() == ConsoleDataType.DateTime
					&& dateValue.equals(other.getDateValue()))
				return true;

		}

		return false;
	}
}
